#include <iostream>
using std::cout;
using std::endl;

class MetaData {
public:
    MetaData(int size, const std::string &name)
    : _name(name)
    , _size(size)
    {   cout << "MetaData(int, const string &)" << endl;}

    MetaData(const MetaData &other)
    : _name(other._name)
    , _size(other._size)
    {
        std::cout << "MetaData(const MetaData &other)" << std::endl;
    }

    MetaData(MetaData &&other)
    : _name(std::move(other._name))
    , _size(other._size)
    {
        std::cout << "MetaData(MetaData &&other)" << std::endl;
    }
    std::string getName() const { return _name; }
    int getSize() const { return _size; }
private:
    std::string _name;
    int _size;
};


class ArrayWrapper {
public:
    ArrayWrapper()
    : _pVals(new int [64])
    , _metadata(64, "ArrayWrapper")
    {   cout << "ArrayWrapper()" << endl;   }

    ArrayWrapper(int n)
    : _pVals(new int[n])
    , _metadata(n, "ArrayWrapper")
    {   cout << "ArrayWrapper(int)" << endl;    }

    ArrayWrapper(const ArrayWrapper & other)
    : _pVals(new int[other._metadata.getSize()])
    , _metadata(other._metadata)
    {
        std::cout << "ArrayWrapper(const ArryWrapper &other)" << std::endl;
        for(int idx = 0; idx != other._metadata.getSize(); ++idx)
        {
            _pVals[idx] = other._pVals[idx];
        }
    }

    //当自定义了类类型时，如果要表达移动语义，切记
    //其每一个数据成员都应该要采用移动语义进行操作
    //否则，移动语义表达式不彻底的
    ArrayWrapper(ArrayWrapper &&other)//移动构造函数
    : _pVals(other._pVals)
    , _metadata(std::move(other._metadata))//必须要加上std::move函数
    {
        std::cout << "ArrayWrapper(ArrayWrapper &&other)" << std::endl;
        other._pVals = nullptr;
    }

    ~ArrayWrapper()
    {
        delete [] _pVals;
        _pVals = nullptr;
        cout << "~ArrayWrapper()" << endl;
    }

private:
    int * _pVals;
    MetaData _metadata;
};

void test0()
{
    ArrayWrapper aw;
    //ArrayWrapper aw2 = aw;

    cout << endl;
    ArrayWrapper aw3 = std::move(aw);

}


int main()
{
    test0();
    return 0;
}

